/*
 * RegistroArbol.cpp
 *
 *  Created on: 20/04/2013
 *      Author: juan
 */

#include "RegistroArbol.h"

RegistroArbol::RegistroArbol(Clave clave) {
	this->clave = clave ;
	this->longitud = clave.getTamanio();
	this->id = new list<unsigned int>();
	cantidad_ids = 0;

}

RegistroArbol::~RegistroArbol() {
	delete this->id;
}

int RegistroArbol::persistir(char* ss){
	//Devuelve la cantidad de bytes usados
	short unsigned int bytes_ocupados = 0;

//	memcpy(ss,&longitud,sizeof(short unsigned int));
//	bytes_ocupados += sizeof(short unsigned int);
//
//	memcpy(ss+bytes_ocupados,clave.c_str(),clave.size());
//	bytes_ocupados += clave.size();

	bytes_ocupados += clave.persistir(ss);

	memcpy(ss+bytes_ocupados, &cantidad_ids, sizeof(short unsigned int));
	bytes_ocupados += sizeof(short unsigned int);

	list<unsigned int>::iterator it;
	for (it = id->begin(); it != id->end(); it++){
		unsigned int id_actual = *it;
		memcpy(ss+bytes_ocupados, &id_actual,sizeof(unsigned int));
		bytes_ocupados += sizeof(unsigned int);
	}
	return bytes_ocupados;
}

int RegistroArbol::bytesOcupados(){
	int bytes_oc = 0;
	bytes_oc += ( sizeof(short unsigned int) * 2 ); //longitud y cantidad_ids
	bytes_oc += clave.getTamanio(); //los bytes de la clave
	bytes_oc += (sizeof(unsigned int) * cantidad_ids); //un short un int por cada id
	return bytes_oc;
}

Clave RegistroArbol::getClave(){
	return clave;
}

int RegistroArbol::getLongitud(){return longitud;}

int RegistroArbol::agregar(Clave cancion, unsigned int id){

	if (tieneElId(id)){
		return 3; //El id ya esta contenido
	} else if (clave == cancion){ //Es un chequeo extra... innecesario capaz
		this->id->push_back(id);
		cantidad_ids += 1;
		return 1; //Se agrego correctamente
	}else{
		return 0; //Hubo un error
	}
}


int RegistroArbol::borrar(Clave cancion, unsigned int id){
	//Devuelve 3 si el id fue borrado exitosamente y el registro quedo vacio
	// 2 si el id fue borrado exitosamente
	// 1 si no contenia la clave o el id
	// 0 si hubo un error
	if (tieneElId(id)){
		//Itero la lista de ids y borro.
		list<unsigned int>::iterator it;
		for (it = this->id->begin(); it != this->id->end(); it++){
			if (*it == id){
				this->id->erase(it);
				break;
			}
		}
		cantidad_ids --;
		if (this->isEmpty()){
			return 3;
		}
		return 2;
	} else if (clave==cancion){ //Es un chequeo extra... innecesario capaz
		return 1; //El id no esta contenido en este registro
	}else{
		return 0; //Hubo un error
	}
}

bool RegistroArbol::tieneElId(unsigned int id){
	//Devuelve true si el id ya esta contenido, false en otro caso.
	list<unsigned int>::iterator it;
	for (it = (this->id)->begin(); it != (this->id)->end(); it++){
		if (*it == id){
			return true;
		}
	}
	return false;
}

void RegistroArbol::mostrar(){
	cout << "(";
	cout << clave.getClaveString();
	cout << ") ";
	list<unsigned int>::iterator it;
	for (it = (this->id)->begin(); it != (this->id)->end(); it++){
		cout << (*it);
		cout << " ";
	}
}

bool RegistroArbol::isEmpty()
{
	return cantidad_ids==0;
}

list<unsigned int> * RegistroArbol::getId(){return id;}
